package com.hyj.serve.manage.configure.exception;

import com.alibaba.fastjson.JSON;
import com.hyj.serve.manage.configure.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.AccessDeniedException;
import java.util.ArrayList;
import java.util.List;

/**
 * API异常处理
 * @author msi_hyj
 *
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

	
	@ExceptionHandler
	public Object exceptionHandler(Exception e, HttpServletRequest req, HttpServletResponse res) throws IOException {
		int status = 500;
		
		log.error("请求错误，【"+ req.getRequestURI() +"】", e);
		Result<Object> r = Result.fail("系统错误").build();
		if(e instanceof ServiceException){
			ServiceException ee = ((ServiceException) e);
			r = ee.getResult();
			if(ee.getHttpStatus() != null){
				status = ee.getHttpStatus().value();
			}
		} else if(e instanceof BindException){ // 验证异常
			BindException e1 = (BindException)e;
			handlerValidException(r, e1.getAllErrors());
		} else if(e instanceof AccessDeniedException) { // 没有权限
			status = 403;
			r.setCode(403);
			r.setMessage(e.getMessage());
		}

		
		res.setContentType(MediaType.APPLICATION_JSON_VALUE);
		res.setCharacterEncoding("UTF-8");
		String string = JSON.toJSONString(r);
		
//		PrintWriter writer = res.getWriter();
//		writer.print(string);
//		writer.flush();
		
		return ResponseEntity.status(status).body(string);
	}
	
	private void handlerValidException(Result<Object> r, List<ObjectError> allErrors){
		List<String> errs = new ArrayList<>(allErrors.size());
		for(ObjectError error : allErrors) {
			errs.add(error.getDefaultMessage());
		}
		r.setCode(601);
		r.setMessage("表单验证失败");
		r.setData(errs);
	}
}
